/*
 * RimmingtonAnyMiner.java v.1.7 By Linux_Communist www.chemfy.fi First release
 * 25.03.08
 * 
 * 
 * Features: -Can bank or power -Can mine clay, tin, copper, iron, gold -Anti
 * random combat, losing tools, loss of pickaxe head, gas -Shows ores mined and
 * runtime. -Anti logout for gold mining. -Can now wear the pickaxe
 * 
 * Now has html description page.
 * 
 */

import java.awt.Color;
import java.awt.Graphics;
import java.util.Map;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSItemTile;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class RimmingtonAnyMiner extends Script implements PaintListener {

	public static final int[] bankWindows = new int[] { 11758 };

	public static final int[] clayRockTypes = new int[] { 9711, 9713 };

	// of
	// iron
	// rocks
	public static final int[] copperRockTypes = new int[] { 9708, 9709, 9710 };

	public static final int[] dropThis = new int[] { 438, 434, 436, 440, 444 };
	public static final int[] gemTypes = new int[] { 1617, 1619, 1621, 1623 };
	public static final int[] goldRockTypes = new int[] { 9722, 9720 };
	public static final int[] ironRockTypes = new int[] { 9717, 9718, 9719 }; // ID:s
	public static final int[] oreTypes = new int[] { 438, 434, 436, 440, 444 };
	public static final int[] pickaxeHeads = new int[] { 480, 482, 484, 486,
			488, 490 };
	public static final int[] pickaxeTypes = new int[] { 1275, 1265, 1269,
			1267, 1273, 1271 };
	public static final RSTile[] revpath = new RSTile[] {
			new RSTile(3012, 3356), new RSTile(3007, 3349),
			new RSTile(3006, 3341), new RSTile(3006, 3333),
			new RSTile(3006, 3325), new RSTile(3006, 3317),
			new RSTile(3006, 3309), new RSTile(3003, 3301),
			new RSTile(2998, 3294), new RSTile(2995, 3286),
			new RSTile(2995, 3278), new RSTile(2994, 3270),
			new RSTile(2994, 3262), new RSTile(2987, 3258),
			new RSTile(2979, 3255), new RSTile(2973, 3249),
			new RSTile(2971, 3241), new RSTile(2980, 3238) };
	public static final int[] smokingRocks = new int[] { 11177, 11178, 11179,
			11180, 11181, 11182 };
	public static final int[] tinRockTypes = new int[] { 9714, 9716 };
	public RSTile[] bankpath = reversePath(RimmingtonAnyMiner.revpath);
	int copOrTin = 1;
	int gemCount = 0;
	public int gemsBanked = 0;
	int mineWhat = -1;
	public int oreBanked = 0;
	int oreCount = 0;
	boolean powerMine, wearPickaxe;
	int progress = 0;
	int randomTime = random(0, 20000);
	public int startLevel = 0;
	public long startTime = System.currentTimeMillis();
	public int startXP = 0;

	public long time = System.currentTimeMillis();

	public void checkForTool() {
		boolean tool = tool();
		int i, j = 0;

		if (!tool) {
			for (i = 0; i < bank.getItemArray().length; i++) {
				for (j = 0; j < RimmingtonAnyMiner.pickaxeTypes.length; j++) {

					if (bank.getItemArray()[i] == RimmingtonAnyMiner.pickaxeTypes[j]) {
						bank.withdraw(RimmingtonAnyMiner.pickaxeTypes[j], 1);
						tool = true;
					}
					if (tool) {
						break;
					}
				}
				if (tool) {
					break;
				}
			}

		}

	}

	public int doWePower(final String howToMine) {
		if (howToMine.contains("p")) // Same as above but for p as in power
		// or b as in bank
		{
			return 1;
		} else if (howToMine.contains("b")) {
			return 2;
		} else {
			log("To use this script give arguments tin, copper, clay, gold, iron to know what to mine or both to mine tin and copper and power or bank and are should pickaxe be worn no or yes like \"bank,iron,no\"");
			return 0;
		}
	}

	public void dropOre() { // Dropping items that are set on dropThis array
		boolean drop = false;
		for (int i = 0; i < 27; i++) {
			for (final int element : RimmingtonAnyMiner.dropThis) {
				if (element == getInventoryItems()[i].getID()) {
					drop = true;

				}
			}
			if (drop) {
				atInventoryItem(getInventoryItems()[i].getID(), "Drop");
				wait(random(1000, 2000));
				drop = false;
			}

		}
	}

	@Override
	public String getAuthor() {

		return "Linux_Communist";

	}

	@Override
	public String getName() {

		return "Rimmington anything miner";

	}

	@Override
	public String getScriptCategory() {
		return "Mining";
	}

	@Override
	public String getScriptDescription() {
		return "<html>\n" + "<head></head>\n" + "<body>\n" + "<center>"
				+ "<h2>"
				+ getName()
				+ "</h2>"
				+ "</center>\n"
				+ "<b>Author:</b> "
				+ getAuthor()
				+ "<br />"
				+ "<b>Website:</b> <a href=\"http://www.chemfy.fi/\">http://www.chemfy.fi/</a><br />"
				+ "<b>Version:</b> "
				+ getVersion()
				+ "<br />"
				+
				/*
				 * "This script need arguments bank or power,clay or tin or
				 * copper or iron or gold or both like \"bank,both,no\" <br />"
				 * +
				 * "You can mine both copper and tin by giving argument both.<br />"
				 * +
				 */
				"<b>Features:</b>"
				+ "<ul><li>Can bank or power</li>"
				+ "<li>Can mine clay, tin, copper, iron, gold.</li>"
				+ "<li>Anti random combat, losing tools, loss of pickaxe head, gas.</li>"
				+ "<li>Shows ores mined and runtime.</li>"
				+ "<li>Anti logout for gold mining.</li>"
				+ "<li>Can now wear the pickaxe.</li></ul>"
				+

				"<b>Arguments<b><br />"
				+ "<form>Bank:<input type=\"radio\" name=\"how\" value=\"bank\" checked=\"checked\"> "
				+ "Power:<input type=\"radio\" name=\"how\" value=\"power\"><br /></form>"
				+

				"<form>Copper:<input type=\"radio\" name=\"what\" value=\"copper\"> "
				+ "Tin:<input type=\"radio\" name=\"what\" value=\"tin\"> "
				+ "Copper & Tin:<input type=\"radio\" name=\"what\" value=\"both\"> "
				+ "Iron:<input type=\"radio\" name=\"what\" value=\"iron\" checked=\"checked\"> "
				+ "Gold:<input type=\"radio\" name=\"what\" value=\"gold\"> "
				+ "Clay:<input type=\"radio\" name=\"what\" value=\"clay\"><br /></form>"
				+

				"<form>Wear pickaxe? Yes: <input type=\"radio\" name=\"wear\" value=\"yes\">  No:<input type=\"radio\" name=\"wear\" value=\"no\" checked=\"checked\"></form>"
				+

				"</body>\n" + "</html>";
	}

	@Override
	public double getVersion() {

		return 1.7;

	}

	@Override
	public int loop() {
		if (isLoggedIn() && startLevel == 0) {
			startLevel = skills.getCurrentSkillLevel(14);
			startXP = skills.getCurrentSkillExp(14);
		}

		switch (progress) {
		case 0:

			if (distanceTo(RimmingtonAnyMiner.revpath[0]) < 10) {
				progress = 2;
				return random(500, 750);
			}
			if (isInventoryFull() && !powerMine) {

				progress++;
				setRun(true);
				return random(1000, 1500);
			} else if (isInventoryFull() && powerMine) // If we power and
			// have inv full
			// drops fish
			{
				dropOre();
			}
			if (getMyPlayer().isInCombat() && !getMyPlayer().isMoving()) // If
			// we
			// are
			// in
			// combat
			// runs
			// away
			{
				runAway();
				return random(400, 700);

			}
			if (findObject(RimmingtonAnyMiner.smokingRocks) == null) {
				if (getMyPlayer().getAnimation() == 625
						|| getMyPlayer().getAnimation() == 624
						|| getMyPlayer().isMoving()) {
					return random(350, 500);
				}
			}

			if (!tool()) {
				if ((inventoryContains(466) || equipmentContains(466))
						&& getGroundItemByID(15,
								RimmingtonAnyMiner.pickaxeHeads) != null) {
					final RSItemTile item = getGroundItemByID(20,
							RimmingtonAnyMiner.pickaxeHeads);

					if (item != null && !getMyPlayer().isMoving()) {
						if (distanceTo(item) > 8) {
							walkTileMM(item);
							return random(1000, 2000);
						}

						atTile(item, "Take");
						return random(500, 1000);

					}
				} else if (equipmentContains(466)
						&& inventoryContainsOneOf(RimmingtonAnyMiner.pickaxeHeads)) {
					if (getCurrentTab() == Constants.TAB_EQUIPMENT) {
						clickMouse(575, 300, 25, 15, true);
						wait(random(1000, 2000));
					} else {
						openTab(Constants.TAB_EQUIPMENT);
					}
					return random(1000, 2000);
				} else if (inventoryContains(466)
						&& inventoryContainsOneOf(RimmingtonAnyMiner.pickaxeHeads)) {
					useItem(
							getInventoryItemByID(RimmingtonAnyMiner.pickaxeHeads),
							getInventoryItemByID(466));
					return random(1000, 2000);

				} else {
					log("No pickaxe");
					progress++;
					return random(300, 500);
				}
			}

			if (wearPickaxe) {

				for (final int element : RimmingtonAnyMiner.pickaxeTypes) {

					if (inventoryContains(element)) {

						atInventoryItem(element, "Wield");
					}
				}
			}
			mine();
			return random(500, 750);
		case 1: // Walking
			if (getMyPlayer().isMoving()) {
				return random(250, 500);
			}

			if (distanceTo(bankpath[bankpath.length - 1]) < 8) {

				progress++;
				return random(500, 750);
			}

			walkPathMM(randomizePath(bankpath, 2, 2), 15);
			return random(3500, 4000);
		case 2: // Banking

			final RSObject bankWindow = findObject(RimmingtonAnyMiner.bankWindows);
			if (distanceTo(bankWindow.getLocation()) > 5) {
				walkTileMM(bankWindow.getLocation());
				return random(500, 750);
			}
			if (!bank.getInterface().isValid()) {
				atObject(bankWindow, "Use-quickly");
				return random(1500, 1750);
			}
			if (oreCount == 0) {
				oreCount = getInventoryCount(RimmingtonAnyMiner.oreTypes);
			}
			if (gemCount == 0) {
				gemCount = getInventoryCount(RimmingtonAnyMiner.gemTypes);
			}
			bank.depositAllExcept(RimmingtonAnyMiner.pickaxeTypes);

			checkForTool(); // Checks if we have a net/pole and enough bait
			if (!isInventoryFull() && tool()) { // if inventory isnt full
				// goes to second progress
				oreBanked += oreCount;
				oreCount = 0;
				gemsBanked += gemCount;
				gemCount = 0;
				progress++;
				if (copOrTin == 1) {
					copOrTin = 2;
				} else if (copOrTin == 2) {
					copOrTin = 1;
				}
			}
			bank.close(); // close bank window
			return random(500, 750);

		case 3: // Walking back
			if (getMyPlayer().isMoving()) {
				return random(250, 500);
			}
			if (distanceTo(bankpath[0]) < 8) {
				progress = 0;
				return random(500, 750);
			}
			walkPathMM(randomizePath(RimmingtonAnyMiner.revpath, 2, 2), 15);
			return random(3500, 4000);
		}
		return -1;
	}

	public void mine() {
		RSObject obj = null;
		switch (mineWhat) {
		case 1:
			obj = findObject(RimmingtonAnyMiner.ironRockTypes);// find object by
			// rockTypes
			break;
		case 2:
			obj = findObject(RimmingtonAnyMiner.copperRockTypes);// find object
			// by
			// rockTypes
			break;
		case 3:
			obj = findObject(RimmingtonAnyMiner.tinRockTypes);// find object by
			// rockTypes
			break;
		case 4:
			if (copOrTin == 1) {
				obj = findObject(RimmingtonAnyMiner.tinRockTypes);// find object
				// by
				// rockTypes
			} else if (copOrTin == 2) {
				obj = findObject(RimmingtonAnyMiner.copperRockTypes);// find
				// object
				// by
				// rockTypes
			}
			break;
		case 5:
			if (findObject(RimmingtonAnyMiner.smokingRocks) == null) {
				obj = findObject(RimmingtonAnyMiner.goldRockTypes);// find
				// object by
				// rockTypes
			} else {
				walkTileMM(getMyPlayer().getLocation());
				wait(random(4000, 6000));
			}
			break;
		case 6:
			obj = findObject(RimmingtonAnyMiner.clayRockTypes);
			break;
		default:
			log("Doesn't know what to mine!?!? This is a big problem");
			break;
		}

		if (obj == null || distanceTo(obj.getLocation()) > 25) {
			if (mineWhat != 5) {
				log("No (nearby) mining spot. This sucks.");
			} else {
				if (System.currentTimeMillis() - time > 30000 + randomTime) {
					final int oldTab = getCurrentTab();
					int tempNumber = random(0, 13);
					time = System.currentTimeMillis();
					randomTime = random(0, 20000);
					while (oldTab == getCurrentTab()) {
						if (getCurrentTab() == tempNumber) {
							tempNumber = random(0, 13);
						} else {
							openTab(tempNumber);
						}
					}
				}
			}
		} else if (distanceTo(obj.getLocation()) > 3) {
			walkTileMM(obj.getLocation()); // This was done because the
			// walktile misses alittle
		} else {
			atObject(obj, "Mine");
			if (mineWhat == 5) {
				time = System.currentTimeMillis();
				randomTime = random(0, 20000);
			}
		}
	}

	@Override
	public void onFinish() {
		Bot.getEventManager().removeListener(PaintListener.class, this);
	}

	public void onRepaint(final Graphics g) {
		if (isLoggedIn()) {
			long millis = System.currentTimeMillis() - startTime;
			final long hours = millis / (1000 * 60 * 60);
			millis -= hours * 1000 * 60 * 60;
			final long minutes = millis / (1000 * 60);
			millis -= minutes * 1000 * 60;
			final long seconds = millis / 1000;
			final int XPChange = skills.getCurrentSkillExp(14) - startXP;
			final int LevelChange = skills.getCurrentSkillLevel(14)
					- startLevel;
			g.setColor(Color.red);
			g.drawString("Banked " + Integer.toString(oreBanked) + " ores and "
					+ Integer.toString(gemsBanked) + " gems.", 200, 365);
			g.drawString("Runtime: " + hours + " hours " + minutes
					+ " minutes " + seconds + " seconds.", 200, 380);
			g.drawString("Current: " + skills.getCurrentSkillLevel(14)
					+ " levels and " + skills.getCurrentSkillExp(14) + " exp.",
					200, 395);
			g.drawString("Gained: " + LevelChange + " levels and " + XPChange
					+ " exp.", 200, 410);
			g.drawString(skills.getXPToNextLevel(14)
					+ " XP to next level, we are "
					+ skills.getPercentToNextLevel(14) + "% to next level.",
					200, 425);
		}
	}

	@Override
	public boolean onStart(final Map<String, String> args) {

		log("Roskaaaa");

		if (args.get("wear").equals("yes")) {
			wearPickaxe = true;
		} else {
			wearPickaxe = false;
		}

		mineWhat = whatToMine(args.get("what"));

		if (args.get("how").equals("power")) {
			powerMine = true;
		} else {
			powerMine = false;
		}

		oreBanked = 0;
		gemsBanked = 0;
		startTime = System.currentTimeMillis();
		if (isLoggedIn()) {
			startLevel = skills.getCurrentSkillLevel(14);
			startXP = skills.getCurrentSkillExp(14);
		}
		return true;
	}

	public void runAway() { // running away and running back after a while
		RSTile foo, bar;
		foo = getMyPlayer().getLocation();
		setRun(true);

		bar = new RSTile(foo.getX() + random(8, 10), foo.getY() + random(8, 10));

		walkTileMM(bar);
		while (getMyPlayer().isMoving()) {
			wait(random(2000, 4000));
		}
		wait(random(1000, 2000));
		walkTileMM(foo);
	}

	public boolean tool() {
		for (final int element : RimmingtonAnyMiner.pickaxeTypes) {
			if (inventoryContains(element) || equipmentContains(element)) {
				return true;
			}
		}
		return false;
	}

	public int whatToMine(final String rockName) {
		if (rockName.contains("b")) {
			return 4;
		}
		if (rockName.contains("p")) {
			return 2;
		}
		if (rockName.contains("t")) {
			return 3;
		}
		if (rockName.contains("i")) {
			return 1;
		}
		if (rockName.contains("y")) {
			return 6;
		}
		if (rockName.contains("g")) {
			return 5;
		}
		log("To use this script give arguments tin, copper, clay, gold, iron to know what to mine or both to mine tin and copper and power or bank and are should pickaxe be worn no or yes like \"bank,iron,no\"");
		return -1;
	}

}
